//Customer Agent
//
// This function represents the logic and activities of a Customer in the movie theater simulation.
// This function will be forked onto a thread during initialization.
//

#define _CRT_RAND_S
#include "CustomerAgent.h"
#include "globalsExtern.cc"
#include "utility.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void CustomerAgentExecute(int arg) {
	// Customer Agent local data goes here
	int GroupID = arg;
	
	// Customer Agent running code should go here.
	DEBUG('c', "%s: Thread now running.\n", currentThread->getName());
	DEBUG('R', "%s has entered the movie theater.\n",currentThread->getName());
	
	groupLock[GroupID]->Acquire();
	groupCustomerCondition[GroupID]->Wait(groupLock[GroupID]);
	
	// Check if enum = FOOD
	while(true){
		//asking for food
		if(groupWhiteboard[GroupID]->getState() == 0){
					incrementFood(GroupID);
				
				if (groupWhiteboard[GroupID]->getNumModified() == groupWhiteboard[GroupID]->getGroupSize()){
					DEBUG('c', "%s: I am the last one in the group. Waking up head customer.\n", currentThread->getName());
					headCustomerCondition[GroupID]->Signal(groupLock[GroupID]);
				}
		}
		//asking for bathroom
		else if(groupWhiteboard[GroupID]->getState() == 1){
			if(wantsToGoToBathroom(GroupID) == 1){
				if (groupWhiteboard[GroupID]->getNumModified() == groupWhiteboard[GroupID]->getGroupSize()){
					DEBUG('c', "%s: I am the last one in the group. Waking up head customer.\n", currentThread->getName());
					headCustomerCondition[GroupID]->Signal(groupLock[GroupID]);
				}
				groupCustomerCondition[GroupID]->Wait(groupLock[GroupID]);
				DEBUG('R', "%s is leaving the bathroom.\n", currentThread->getName());
				DEBUG('R', "%s has left the movie theater.\n", currentThread->getName());
				return;
			}
			if (groupWhiteboard[GroupID]->getNumModified() == groupWhiteboard[GroupID]->getGroupSize()){
					DEBUG('c', "%s: I am the last one in the group. Waking up head customer.\n", currentThread->getName());
					headCustomerCondition[GroupID]->Signal(groupLock[GroupID]);
			}
		}
		else{ // Done state, should leave bathroom
			DEBUG('R', "%s has left the movie theater.\n", currentThread->getName());
			return;
		}
		DEBUG('c', "%s: Going to sleep.\n", currentThread->getName());
		groupCustomerCondition[GroupID]->Wait(groupLock[GroupID]);
	}
	
}

void incrementFood(int GroupID) {
	int popcornChance = rand() % 1000 + 1;
	int sodaChance = rand() % 1000 +1;
	int wantPopcorn = 0;
	int wantSoda = 0;
	if (popcornChance <= 750){
		groupWhiteboard[GroupID]->incrementPopcornTally(1);
		wantPopcorn = 1;
	}
	if (sodaChance <= 750){
		groupWhiteboard[GroupID]->incrementSodaTally(1);
		wantSoda = 1;
	}
	groupWhiteboard[GroupID]->incrementNumModified();
	DEBUG('R', "%s wants %d popcorn and %d soda.\n", currentThread->getName(),wantPopcorn,wantSoda);
}

int wantsToGoToBathroom(int GroupID) {
	int bathroomChance = rand() % 1000 + 1;
	int wantBathroom = 0;
	if (bathroomChance <= 250){
		groupWhiteboard[GroupID]->incrementBathroomTally(1);
		groupWhiteboard[GroupID]->setSomeoneNeedsBathroom(true);
		wantBathroom = 1;
	}
	groupWhiteboard[GroupID]->incrementNumModified();
	if (wantBathroom == 1){
		DEBUG('R', "%s is going to the bathroom.\n", currentThread->getName());
	}
	return wantBathroom;
}
